package cn.minsh.lims.eoms.modules.app.service.impl;

import cn.minsh.lims.eoms.common.exception.RRException;
import cn.minsh.lims.eoms.common.utils.ObjectToMapUtils;
import cn.minsh.lims.eoms.common.utils.PageUtils;
import cn.minsh.lims.eoms.common.utils.Query;
import cn.minsh.lims.eoms.modules.app.controller.req.InspectionPlanListReq;
import cn.minsh.lims.eoms.modules.app.controller.req.InspectionPlanReq;
import cn.minsh.lims.eoms.modules.app.controller.res.InspectionPlanRes;
import cn.minsh.lims.eoms.modules.app.dao.InspectionPlanDao;
import cn.minsh.lims.eoms.modules.app.entity.*;
import cn.minsh.lims.eoms.modules.app.enums.BusiTypeEnum;
import cn.minsh.lims.eoms.modules.app.enums.FrequencyEnum;
import cn.minsh.lims.eoms.modules.app.enums.PlanStatusEnum;
import cn.minsh.lims.eoms.modules.app.service.*;
import cn.minsh.lims.eoms.modules.app.utils.LocalDateUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service("inspectionPlanService")
public class InspectionPlanServiceImpl extends ServiceImpl<InspectionPlanDao, InspectionPlanEntity> implements InspectionPlanService {

    @Autowired
    private PlanScopeService planScopeService ;
    @Autowired
    private PlanRemindService planRemindService ;
    @Autowired
    private PlanContentService planContentService ;
    @Autowired
    private PlanAgentService planAgentService ;

    @Override
    public PageUtils<InspectionPlanRes> queryPage(InspectionPlanListReq req) {
        QueryWrapper<InspectionPlanEntity> queryWrapper = new QueryWrapper() ;
        if(req.getStatus()!=null) {
            queryWrapper.eq("status",req.getStatus()) ;
        }
        if (StringUtils.isNotBlank(req.getName())){
            queryWrapper.like("name","%"+req.getName()+"%") ;
        }
        if (!CollectionUtils.isEmpty(req.getCreateByList())){
            queryWrapper.in("create_by",req.getCreateByList()) ;
        }
        if (!CollectionUtils.isEmpty(req.getAgentIdList())){
            queryWrapper.in("agent_id",req.getAgentIdList()) ;
        }
        queryWrapper.eq("is_del",0) ;
        if (StringUtils.isNotBlank(req.getOrder()) && StringUtils.isNotBlank(req.getSort())){
            queryWrapper.orderBy(StringUtils.isNotBlank(req.getOrder()) && StringUtils.isNotBlank(req.getSort()),"asc".equals(req.getSort().toLowerCase()),req.getOrder());
        }else {
            queryWrapper.orderByDesc("create_time");
        }
        IPage<InspectionPlanEntity> page = this.page(
                new Query<InspectionPlanEntity>().getPage(ObjectToMapUtils.setConditionMap(req)),
                queryWrapper
        );

        List<InspectionPlanRes> retList = new ArrayList<>() ;

        IPage<InspectionPlanRes> retPage = new Page<>(page.getCurrent(),page.getSize()) ;
        retPage.setPages(page.getPages()) ;
        retPage.setTotal(page.getTotal()) ;

        if (!CollectionUtils.isEmpty(page.getRecords())){
            //查询所有范围
            QueryWrapper<PlanScopeEntity> planScopeEntityQueryWrapper = new QueryWrapper<>() ;
            planScopeEntityQueryWrapper.eq("type", BusiTypeEnum.INSPECTIONPLAN.getCode()) ;
            List<PlanScopeEntity> planScopeEntityList= planScopeService.list(planScopeEntityQueryWrapper) ;
            //巡检经办人
            QueryWrapper<PlanAgentEntity> planAgentEntityQueryWrapper = new QueryWrapper<>() ;
            planAgentEntityQueryWrapper.eq("type", BusiTypeEnum.INSPECTIONPLAN.getCode()) ;
            List<PlanAgentEntity> planAgentEntityList = planAgentService.list(planAgentEntityQueryWrapper) ;
            page.getRecords().forEach(e->{
                InspectionPlanRes res = new InspectionPlanRes() ;
                BeanUtils.copyProperties(e,res);
                //添加首次巡检时间
                res.setFirstStartTime(e.getFirstStartTime());
                res.setFirstEndTime(e.getFirstEndTime());
                if (FrequencyEnum.WEEK.getCode().equals(res.getFrequency())){
                    res.setFirstInspectionTime(LocalDateUtils.getWeekTimeStr(e.getFirstStartTime(),e.getFirstEndTime()));
                }else{
                    res.setFirstInspectionTime(LocalDateUtils.getTimeStr(e.getFirstStartTime(),e.getFirstEndTime()));
                }

                res.setStatusDesc(PlanStatusEnum.getDesc(res.getStatus()));
                res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
                if (!CollectionUtils.isEmpty(planScopeEntityList)){
                    res.setScopeIdList(planScopeEntityList.stream().filter(p->p.getPlanId().equals(e.getId())).map(PlanScopeEntity::getScopeId).collect(Collectors.toList()));
                }
                if (!CollectionUtils.isEmpty(planAgentEntityList)){
                    res.setAgentIdList(planAgentEntityList.stream().filter(pa->pa.getPlanId().equals(e.getId())).map(PlanAgentEntity::getAgentId).collect(Collectors.toList()));
                }
                retList.add(res) ;
            });
        }

        retPage.setRecords(retList) ;
        return new PageUtils(retPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean savePlan(InspectionPlanReq req,Long userId) {
        //1、添加计划
        InspectionPlanEntity planEntity = new InspectionPlanEntity() ;
        BeanUtils.copyProperties(req,planEntity);
        //判断首次开始时间与当期那时间比较
        if (req.getFirstStartTime().before(new Date())){
            planEntity.setStatus(PlanStatusEnum.STARTED.getCode());
        }else{
            planEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
        }
        //判断结束时间与当前时间比较
        if (req.getInvalidTime() != null && req.getInvalidTime().before(new Date())){
            planEntity.setStatus(PlanStatusEnum.OVER.getCode());
        }

        planEntity.setNum(0);
        planEntity.setIsDel(0);
        planEntity.setCreateBy(userId);
        planEntity.setCreateTime(new Date());
        planEntity.setUpdateBy(userId);
        planEntity.setUpdateTime(new Date());
        boolean bool = save(planEntity) ;

        if (bool) {
            Long planId = planEntity.getId();
            //添加经办人列表
            if (!CollectionUtils.isEmpty(req.getAgentIdList())){
                List<PlanAgentEntity> planAgentEntityList = new ArrayList<>() ;
                req.getAgentIdList().forEach(pa->{
                    PlanAgentEntity planAgentEntity = new PlanAgentEntity() ;
                    planAgentEntity.setAgentId(pa);
                    planAgentEntity.setPlanId(planId);
                    planAgentEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                    planAgentEntityList.add(planAgentEntity) ;
                });
                planAgentService.saveBatch(planAgentEntityList) ;
            }
            //2、添加巡检范围
            List<PlanScopeEntity> planScopeEntityList = new ArrayList<>();
            req.getPlanScopeList().stream().forEach(e -> {
                PlanScopeEntity planScopeEntity = new PlanScopeEntity();
                planScopeEntity.setPlanId(planId);
                planScopeEntity.setScopeId(e);
                planScopeEntity.setIsDel(0);
                planScopeEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                planScopeEntityList.add(planScopeEntity);
            });
            planScopeService.saveBatch(planScopeEntityList);

            //3、添加巡检提醒
            List<PlanRemindEntity> remindEntities = new ArrayList<>();
            if (!CollectionUtils.isEmpty(req.getPlanRemindList())) {
                req.getPlanRemindList().stream().forEach(e -> {
                    PlanRemindEntity remindEntity = new PlanRemindEntity();
                    remindEntity.setLeadTime(e);
                    remindEntity.setPlanId(planId);
                    remindEntity.setIsDel(0);
                    remindEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                    remindEntities.add(remindEntity);
                });
                planRemindService.saveBatch(remindEntities);
            }
            //4、添加巡检内容
            if (!CollectionUtils.isEmpty(req.getPlanContentList())) {
                List<PlanContentEntity> contentEntities = new ArrayList<>();
                req.getPlanContentList().stream().forEach(e -> {
                    PlanContentEntity contentEntity = new PlanContentEntity();
                    contentEntity.setContent(e);
                    contentEntity.setPlanId(planId);
                    contentEntity.setIsDel(0);
                    contentEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                    contentEntities.add(contentEntity);
                });
                planContentService.saveBatch(contentEntities);
            }
        }
        return bool;
    }

    @Override
    public Boolean updatePlan(InspectionPlanReq req,Long userId) {
        //1、修改计划
        InspectionPlanEntity planEntity = new InspectionPlanEntity() ;
        BeanUtils.copyProperties(req,planEntity);
        //1.1、判断首次开始时间与当期那时间比较
        if (req.getFirstStartTime().before(new Date())){
            planEntity.setStatus(PlanStatusEnum.STARTED.getCode());
        }else{
            planEntity.setStatus(PlanStatusEnum.NOT_STARTED.getCode());
        }
        //1.2、判断结束时间与当前时间比较
        if (req.getInvalidTime() != null && req.getInvalidTime().before(new Date())){
            planEntity.setStatus(PlanStatusEnum.OVER.getCode());
        }
        planEntity.setUpdateTime(new Date());
        planEntity.setUpdateBy(userId);
        boolean bool = updateById(planEntity) ;

        if (bool) {
            Long planId = planEntity.getId();
            //添加经办人列表
            planAgentService.deleteByTypeAndPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),planId) ;
            if (!CollectionUtils.isEmpty(req.getAgentIdList())){
                List<PlanAgentEntity> planAgentEntityList = new ArrayList<>() ;
                req.getAgentIdList().forEach(pa->{
                    PlanAgentEntity planAgentEntity = new PlanAgentEntity() ;
                    planAgentEntity.setAgentId(pa);
                    planAgentEntity.setPlanId(planId);
                    planAgentEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                    planAgentEntityList.add(planAgentEntity) ;
                });
                planAgentService.saveBatch(planAgentEntityList) ;
            }
            //2、添加巡检范围
            //2.1、删除巡检范围
            planScopeService.deleteByPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),planId); ;
            //2.2、添加巡检范围
            List<PlanScopeEntity> planScopeEntityList = new ArrayList<>();
            req.getPlanScopeList().stream().forEach(e -> {
                PlanScopeEntity planScopeEntity = new PlanScopeEntity();
                planScopeEntity.setPlanId(planId);
                planScopeEntity.setIsDel(0);
                planScopeEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                planScopeEntity.setScopeId(e);
                planScopeEntityList.add(planScopeEntity);
            });
            planScopeService.saveBatch(planScopeEntityList);

            //3、添加巡检提醒
            //3.1、删除提醒时间
            planRemindService.deleteByPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),planId); ;
            //3.2、添加提醒时间
            if (!CollectionUtils.isEmpty(req.getPlanRemindList())) {
                List<PlanRemindEntity> remindEntities = new ArrayList<>();
                req.getPlanRemindList().stream().forEach(e -> {
                    PlanRemindEntity remindEntity = new PlanRemindEntity();
                    remindEntity.setPlanId(planId);
                    remindEntity.setIsDel(0);
                    remindEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                    remindEntity.setLeadTime(e);
                    remindEntities.add(remindEntity);
                });
                planRemindService.saveBatch(remindEntities);
            }
            //4、添加巡检内容
            //4.1、删除巡检内容
            planContentService.deleteByPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),planId); ;
            //4.2、添加巡检内容
            List<PlanContentEntity> contentEntityList = new ArrayList<>();
            req.getPlanContentList().stream().forEach(e->{
                PlanContentEntity contentEntity = new PlanContentEntity() ;
                contentEntity.setPlanId(planId);
                contentEntity.setIsDel(0);
                contentEntity.setType(BusiTypeEnum.INSPECTIONPLAN.getCode());
                contentEntity.setContent(e);
                contentEntityList.add(contentEntity) ;
            });
            planContentService.saveBatch(contentEntityList);
        }
        return bool;
    }


    @Override
    public List<InspectionPlanRes> queryInspectionPlanList(Integer status){
        QueryWrapper<InspectionPlanEntity> queryWrapper = new QueryWrapper() ;
        queryWrapper.eq("status",status) ;
        queryWrapper.eq("is_del",0) ;

        List<InspectionPlanEntity> list = this.list(queryWrapper) ;

        List<InspectionPlanRes> retList = new ArrayList<>() ;

        if (!CollectionUtils.isEmpty(list)){
            //查询所有范围
            QueryWrapper<PlanScopeEntity> planScopeEntityQueryWrapper = new QueryWrapper<>() ;
            planScopeEntityQueryWrapper.eq("type",BusiTypeEnum.INSPECTIONPLAN.getCode()) ;
            List<PlanScopeEntity> planScopeEntityList= planScopeService.list(planScopeEntityQueryWrapper) ;
            //查询提醒时间
            QueryWrapper<PlanRemindEntity> remindEntityQueryWrapper = new QueryWrapper<>() ;
            remindEntityQueryWrapper.eq("type",BusiTypeEnum.INSPECTIONPLAN.getCode()) ;
            List<PlanRemindEntity> planRemindEntityList =  planRemindService.list(remindEntityQueryWrapper) ;
            //查询巡检内容
            QueryWrapper<PlanContentEntity> planContentEntityQueryWrapper = new QueryWrapper<>() ;
            planContentEntityQueryWrapper.eq("type",BusiTypeEnum.INSPECTIONPLAN.getCode()) ;
            List<PlanContentEntity> planContentEntityList = planContentService.list(planContentEntityQueryWrapper) ;
            //查询经办人
            QueryWrapper<PlanAgentEntity> planAgentEntityQueryWrapper = new QueryWrapper<>() ;
            planAgentEntityQueryWrapper.eq("type",BusiTypeEnum.INSPECTIONPLAN.getCode()) ;
            List<PlanAgentEntity> planAgentEntityList = planAgentService.list(planAgentEntityQueryWrapper) ;

            list.forEach(e->{
                InspectionPlanRes res = new InspectionPlanRes() ;
                BeanUtils.copyProperties(e,res);
                //添加首次巡检时间
                res.setFirstInspectionTime(LocalDateUtils.getTimeStr(e.getFirstStartTime(),e.getFirstEndTime()));
                res.setFirstStartTime(e.getFirstStartTime());
                res.setFirstEndTime(e.getFirstEndTime());
                res.setStatusDesc(PlanStatusEnum.getDesc(res.getStatus()));
                res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
                if (!CollectionUtils.isEmpty(planScopeEntityList)){
                    res.setScopeIdList(planScopeEntityList.stream().filter(p->(p.getPlanId().equals(e.getId()) && p.getIsDel().equals(0))).map(PlanScopeEntity::getScopeId).collect(Collectors.toList()));
                }

                if (!CollectionUtils.isEmpty(planRemindEntityList)){
                    res.setRemindList(planRemindEntityList.stream().filter(r->(r.getPlanId().equals(e.getId()) && r.getIsDel().equals(0))).map(PlanRemindEntity::getLeadTime).collect(Collectors.toList()));
                }

                if (!CollectionUtils.isEmpty(planContentEntityList)){
                    res.setContentList(planContentEntityList.stream().filter(c ->(c.getPlanId().equals(e.getId()) && c.getIsDel().equals(0))).map(PlanContentEntity::getContent).collect(Collectors.toList()));
                }
                if (!CollectionUtils.isEmpty(planAgentEntityList)) {
                    res.setAgentIdList(planAgentEntityList.stream().filter(pa->pa.getPlanId().equals(e.getId())).map(PlanAgentEntity::getAgentId).collect(Collectors.toList()));
                }
                retList.add(res) ;
            });
        }
        return retList ;
    }

    @Override
    public InspectionPlanRes queryById(Long id) {
        InspectionPlanRes res = new InspectionPlanRes() ;
        //1、查询记录
        InspectionPlanEntity planEntity =  this.getById(id) ;
        if (planEntity==null || planEntity.getId()==null){
            throw new RRException("巡检计划不存在") ;
        }
        BeanUtils.copyProperties(planEntity,res);

        //添加状态
        res.setStatusDesc(PlanStatusEnum.getDesc(res.getStatus()));
        res.setFrequencyDesc(FrequencyEnum.getDesc(res.getFrequency()));
        //时间
        if (FrequencyEnum.WEEK.getCode().equals(res.getFrequency())){
            res.setFirstInspectionTime(LocalDateUtils.getWeekTimeStr(planEntity.getFirstStartTime(),planEntity.getFirstEndTime()));
        }else{
            res.setFirstInspectionTime(LocalDateUtils.getTimeStr(planEntity.getFirstStartTime(),planEntity.getFirstEndTime()));
        }
        //巡检经办人列表
        List<PlanAgentEntity> planAgentEntityList = planAgentService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),id) ;
        if (!CollectionUtils.isEmpty(planAgentEntityList)){
            res.setAgentIdList(planAgentEntityList.stream().map(PlanAgentEntity::getAgentId).collect(Collectors.toList()));
        }
        //2、巡检设备
        List<PlanScopeEntity> planScopeList = planScopeService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),id) ;
        if (!CollectionUtils.isEmpty(planScopeList)){
            res.setScopeIdList(planScopeList.stream().map(PlanScopeEntity::getScopeId).collect(Collectors.toList()));
        }
        //3、巡检提醒
        List<PlanRemindEntity> planRemindEntityList = planRemindService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),id) ;
        if (!CollectionUtils.isEmpty(planRemindEntityList)){
            res.setRemindList(planRemindEntityList.stream().map(PlanRemindEntity::getLeadTime).collect(Collectors.toList()));
        }
        //4、巡检内容
        List<PlanContentEntity> planContentEntityList = planContentService.listByTypeAndPlanId(BusiTypeEnum.INSPECTIONPLAN.getCode(),id) ;
        if (!CollectionUtils.isEmpty(planContentEntityList)){
            res.setContentList(planContentEntityList.stream().map(PlanContentEntity::getContent).collect(Collectors.toList()));
        }

        return res ;
    }
}